package com.zzy.sample.controller;

import com.zzy.sample.entity.User;
import com.zzy.sample.service.UserService;
import com.zzy.transaction.context.TransactionMeta;
import com.zzy.transaction.manager.TransactionManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("tx")
@Slf4j
public class TestController {

    private AtomicInteger error = new AtomicInteger(0);

    @Autowired
    UserService userService;

    @RequestMapping("1")
    public Object set() {
        List<Runnable> tasks = new ArrayList<>();
        for (int i = 1; i <= 1000; i++) {
            User user = new User();
            user.setId(i);
            user.setName("name" + i);
            tasks.add(() -> userService.save(user));
            // 这里的批次大小，应该比TransactionManager的执行器核心线程小，不然任务放入队列，全部失败
            if (i % 10 == 0) {
                TransactionMeta transactionMeta = TransactionManager.execute(tasks, 2, TimeUnit.SECONDS);
                report(transactionMeta);
                tasks = new ArrayList<>();
            }
        }
        if (tasks.size() > 0) {
            TransactionMeta transactionMeta = TransactionManager.execute(tasks, 2, TimeUnit.SECONDS);
            report(transactionMeta);

        }
        return "ok";
    }


    private void report(TransactionMeta transactionMeta) {
        boolean success = false;
        try {
            success = transactionMeta.get(200, TimeUnit.MILLISECONDS);
            //log.warn("执行结果:{}", success);
        } catch (Exception e) {
            //log.error("执行失败", e);
        }
        if (!success) {
            log.warn(transactionMeta.getExecuteId() + "执行失败");
            log.warn("失败次数：{}", error.incrementAndGet() * 10);
        }
    }
}
